/**
 ******************************************************************************
 * @file           : arduino_motor_speed.c
 * @brief          : Arduino电机转速测量示例
 ******************************************************************************
 * @attention
 *
 * 应用场景：电机转速监测，过滤启动/停止时的干扰
 * 硬件：Arduino + 霍尔传感器
 *
 ******************************************************************************
 */

#include "psv.h"
#include <Arduino.h>

/* 引脚定义 */
#define HALL_SENSOR_PIN     2       /* 霍尔传感器输入引脚（支持中断） */
#define LED_PIN             13      /* 指示灯 */

/* 转速数据 */
volatile uint32_t g_rpm = 0;
volatile uint8_t g_rpm_valid = 0;

/**
 * @brief   Arduino setup函数
 */
void setup()
{
    Serial.begin(115200);
    
    /* 初始化PSV */
    psv_init();
    
    /* 配置霍尔传感器引脚 */
    pinMode(HALL_SENSOR_PIN, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN), 
                    hall_sensor_isr, FALLING);
    
    /* 配置LED */
    pinMode(LED_PIN, OUTPUT);
    
    Serial.println("Motor Speed Monitor Started");
}

/**
 * @brief   霍尔传感器中断服务函数
 */
void hall_sensor_isr()
{
    static uint32_t last_time = 0;
    uint32_t current_time = millis();
    uint32_t period_ms;
    uint32_t rpm;
    
    /* 计算周期 */
    period_ms = current_time - last_time;
    last_time = current_time;
    
    /* 防止抖动 */
    if (period_ms < 10) return;  /* 至少10ms */
    
    /* 计算转速（假设每转1个脉冲） */
    rpm = 60000 / period_ms;  /* RPM = 60000 / 周期(ms) */
    
    /* PSV检测 */
    if (psv_check(rpm))
    {
        g_rpm = rpm;
        g_rpm_valid = 1;
        digitalWrite(LED_PIN, HIGH);  /* 信号有效，LED亮 */
    }
    else
    {
        g_rpm_valid = 0;
        digitalWrite(LED_PIN, LOW);   /* 信号无效，LED灭 */
    }
}

/**
 * @brief   Arduino loop函数
 */
void loop()
{
    static uint32_t last_print_time = 0;
    uint32_t now = millis();
    
    /* 每1秒打印一次 */
    if (now - last_print_time >= 1000)
    {
        last_print_time = now;
        
        if (g_rpm_valid)
        {
            Serial.print("Motor Speed: ");
            Serial.print(g_rpm);
            Serial.println(" RPM [VALID]");
        }
        else
        {
            Serial.println("Motor Speed: --- RPM [INVALID]");
        }
    }
    
    /* 超时检测 */
    static uint32_t last_pulse_time = 0;
    if (now - last_pulse_time > 2000)  /* 2秒无信号 */
    {
        g_rpm = 0;
        g_rpm_valid = 0;
        psv_reset();
    }
}

/**
 * @brief   获取转速（供其他函数调用）
 * @retval  转速（RPM），无效时返回0
 */
uint32_t get_motor_rpm(void)
{
    return g_rpm_valid ? g_rpm : 0;
}
